package com.easylinkin.linkappapi.device.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.common.utils.excel.ExcelConstant;
import com.easylinkin.linkappapi.common.utils.excel.ExcelTools;
import com.easylinkin.linkappapi.common.utils.io.OutputStreamUtil;
import com.easylinkin.linkappapi.device.config.DeviceConfigUtil;
import com.easylinkin.linkappapi.device.constant.DeviceConstant;
import com.easylinkin.linkappapi.device.dao.DevicePositionMapper;
import com.easylinkin.linkappapi.device.entity.DeviceModel;
import com.easylinkin.linkappapi.device.entity.DevicePosition;
import com.easylinkin.linkappapi.device.entity.DevicePositionImage;
import com.easylinkin.linkappapi.device.entity.EnvironmentalArea;
import com.easylinkin.linkappapi.device.entity.vo.DevicePositionVo;
import com.easylinkin.linkappapi.device.mapper.DeviceModelMapper;
import com.easylinkin.linkappapi.device.mapper.DevicePositionImageMapper;
import com.easylinkin.linkappapi.device.mapper.EnvironmentalAreaMapper;
import com.easylinkin.linkappapi.device.service.DevicePositionService;
import com.easylinkin.linkappapi.inspection.service.ElectricBoxService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import java.util.Arrays;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * DevicePosition表服务实现类
 *
 * @author CodeGenerator
 * @date 2022/06/16
 */
@Slf4j
@Service("appDevicePositionService")
public class DevicePositionServiceImpl extends ServiceImpl
        <DevicePositionMapper, DevicePosition> implements DevicePositionService {
    @Resource
    private CommonService commonService;
    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;
    @Resource
    private DeviceConfigUtil deviceConfigUtil;
    @Resource
    private RedisTemplate redisTemplate;
    @Autowired
    private DevicePositionImageMapper devicePositionImageMapper;
    @Autowired
    private DeviceModelMapper deviceModelMapper;
    @Autowired
    private EnvironmentalAreaMapper environmentalAreaMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveMulti(List<DevicePosition> appDevicePositions) {
//        Assert.notEmpty(appDevicePositions,"参数列表为空");
//        删除租户下所有的
        QueryWrapper qw = new QueryWrapper();
        qw.eq("tenant_id", linkappUserContextProducer.getNotNullCurrent().getTenantId());
        baseMapper.delete(qw);
        List<String> codes = appDevicePositions.stream().map(DevicePosition::getDeviceCode).collect(Collectors.toList());
        if (!codes.isEmpty()) {
            QueryWrapper qw2 = new QueryWrapper();
            qw2.in("device_code", codes);
            baseMapper.delete(qw2);
        }

        for (DevicePosition appDevicePosition : appDevicePositions) {
            commonService.setCreateAndModifyInfo(appDevicePosition);
            appDevicePosition.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
            validParamRequired(appDevicePosition);
            validRepeat(appDevicePosition);
            validParamFormat(appDevicePosition);
            save(appDevicePosition);
        }
        return true;
    }


//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @Deprecated
//    public boolean updateMulti(List<DevicePosition> appDevicePositions) {
//        for (DevicePosition appDevicePosition : appDevicePositions) {
//            Assert.notNull(appDevicePosition.getDeviceCode(), "设备编号不能为空");
//            commonService.setModifyInfo(appDevicePosition);
//            appDevicePosition.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
//            validParamFormat(appDevicePosition);
//            updateById(appDevicePosition);
//        }
//        return true;
//    }

    @Override
    public IPage<DevicePositionVo> selectPage(Page page, DevicePositionVo devicePositionVo) {
        devicePositionVo.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        IPage<DevicePositionVo> devicePositionVoIPage = baseMapper.selectPageGlobal(page, devicePositionVo);
        devicePositionVoIPage.getRecords().forEach(item->{
            if(item.getModelId().equals(0)){
                item.setModelName("环境管理");
                //查询对应的区域与名称
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("model_id_",0);
                queryWrapper.eq("is_remove_",0);
                queryWrapper.eq("tenant_id",linkappUserContextProducer.getNotNullCurrent().getTenantId());
                queryWrapper.eq("code_",item.getDeviceCode());
                List<DeviceModel> list = deviceModelMapper.selectList(queryWrapper);
                if(CollectionUtil.isNotEmpty(list)){
                    DeviceModel deviceModel = list.get(0);
                    Integer environmentalAreaId = deviceModel.getEnvironmentalAreaId();
                    if(environmentalAreaId!=null){
                        QueryWrapper queryWrapper1 = new QueryWrapper();
                        queryWrapper1.eq("id",environmentalAreaId);
                        EnvironmentalArea environmentalArea = environmentalAreaMapper
                            .selectOne(queryWrapper1);
                        if(environmentalArea!=null){
                            Integer level = environmentalArea.getLevel();
                            String fullName = environmentalArea.getFullName();
                            item.setLevel(level);
                            item.setAreaFullName(fullName);
                        }
                    }
                }
            }
            if(item.getModelId().equals(-1)){
                item.setModelName("安全管理");
            }
            if (item.getModelId().equals(-2)){
                item.setModelName("劳务管理");
            }
        });
        if (page != null && page.getSize() == -1L) {
            page.setTotal(devicePositionVoIPage.getRecords().size());
        }
        return devicePositionVoIPage;
    }

    @Override
    public IPage<DevicePositionVo> selectPage(Page page, DevicePositionVo devicePositionVo, String usePlace) {
        if (DeviceConstant.PositionUsePlace.ENVIRONMENT.getValue().equals(usePlace)) {
            devicePositionVo.setDeviceTypeNameList(deviceConfigUtil.getPositionEnvironmentDeviceTypes(null));
        }
        IPage<DevicePositionVo> r = selectPage(page, devicePositionVo);
//        environment
        return r;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(List<Long> idList) {
        return removeByIds(idList);
    }

    @Override
    public void export(DevicePositionVo devicePositionVo, HttpServletRequest request, HttpServletResponse
            response) {

        IPage<DevicePositionVo> page = selectPage(new Page(0, -1), devicePositionVo);
        List<DevicePositionVo> records = page.getRecords();
        List
                <DevicePositionVo> appDevicePositionVos = new ArrayList<>();
        for (DevicePosition expert : records) {
            appDevicePositionVos.add(new DevicePositionVo(expert));
        }

        String keyValue = "名称:name,租户id:tenantId";
        String title = "DevicePosition导出数据";
        String fileName = title + ".xls";
        try {
            OutputStream outputStream = OutputStreamUtil
                    .getOutputStream(request, response, fileName);
            ExcelTools.exportExcel(outputStream, keyValue, appDevicePositionVos, ExcelConstant.XLS, title);
            response.flushBuffer();
            outputStream.close();
        } catch (IOException e) {
            log.error("excel导出失败", e);
            throw new RuntimeException("excel导出失败！IOException异常" + e.getMessage());
        } catch (Exception e) {
            log.error("excel导出失败", e);
            throw new RuntimeException("excel导出失败！" + e.getMessage());
        }
    }

    @Override
    public DevicePosition getOneById(Serializable id) {
        return baseMapper.getOneById(id);
    }

    /**
     * 校验重复
     */
    private void validRepeat(DevicePosition appDevicePosition) {
        QueryWrapper<DevicePosition> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_code", appDevicePosition.getDeviceCode());
        queryWrapper.eq("tenant_id", linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<DevicePosition> list = baseMapper.selectList(queryWrapper);
//        if (list.size() == 0) {
//            return;
//        }
        if (list.size() > 0) {
            throw new BusinessException("设备编号有重复");
        }
//        if (StringUtils.isEmpty(appDevicePosition.getDeviceCode())||!appDevicePosition.getDeviceCode().equals(list.get(0).getDeviceCode())) {
//            throw new BusinessException("设备编号有重复");
//        }

    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(DevicePosition appDevicePosition) {
        Assert.notNull(appDevicePosition, "参数为空");
        Assert.notNull(appDevicePosition.getPositionX(), "getPositionX 参数为空");
        Assert.notNull(appDevicePosition.getPositionY(), "getPositionX 参数为空");
        Assert.isTrue(StringUtils.isNotBlank(appDevicePosition.getDeviceCode()), "设备编号为空");
    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(DevicePosition appDevicePosition) {
        Assert.isTrue(appDevicePosition.getDeviceCode() == null || appDevicePosition.getDeviceCode().length() <= 32,
                "名称超长");
    }

    @Override
    public void uploadImage(String smartConstructionSiteImageUrl) {
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        redisTemplate.opsForValue().set("smartConstructionSiteImageUrl" + ":" + tenantId, smartConstructionSiteImageUrl);
        //保存到数据库
        QueryWrapper<DevicePositionImage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id_",tenantId);
        List<DevicePositionImage> positionImages = devicePositionImageMapper
            .selectList(queryWrapper);
        if (positionImages.size() > 0){
            DevicePositionImage image = positionImages.get(0);
            image.setUrl(smartConstructionSiteImageUrl);
            image.setModifyTime(new Date());
            devicePositionImageMapper.updateById(image);
        }else {
            DevicePositionImage image = new DevicePositionImage();
            image.setTenantId(tenantId);
            image.setUrl(smartConstructionSiteImageUrl);
            image.setCreateTime(new Date());
            image.setModifyTime(new Date());
            devicePositionImageMapper.insert(image);
        }
    }

    @Override
    public String getImage(String smartConstructionSiteImageUrl) {
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        Object o = redisTemplate.opsForValue().get(smartConstructionSiteImageUrl + ":" + tenantId);
        if (null == o){
            //从数据库取
            QueryWrapper<DevicePositionImage> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tenant_id_",tenantId);
            List<DevicePositionImage> positionImages = devicePositionImageMapper
                .selectList(queryWrapper);
            if (positionImages.size() > 0){
                return positionImages.get(0).getUrl();
            }else {
                return null;
            }
        }else {
           return  (String)o;
        }
    }

    @Override
    public void clearDevicePosition(List<String> codes) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("tenant_id", linkappUserContextProducer.getNotNullCurrent().getTenantId());
        qw.in("device_code",codes);
        baseMapper.delete(qw);
    }
}

